(function(global){    
    
    var ObjectUtil = {};
    
    /**
     * 获取两个object的交集，即对应的key的value值相同的项.
     * @static 
     */
    ObjectUtil.interfaceArrsection = (function() {
        var getinterfaceArrsectionObj = function(obj) {
            var _this = this, interfaceArrsectionObj = {};
            ObjectUtil.each(_this, function(k, v) {
                if (_this[k] === obj[k]) {
                    interfaceArrsectionObj[k] = v;
                }
            });
            return interfaceArrsectionObj;
        };
        return function(/*obj1, obj2, obj3, ... or [obj1, obj2, obj3, ...]*/) {
            if (arguments[0]) {
                var args = Object.prototype.toString.call(arguments[0]) == '[object Array]' ? arguments[0] : arguments, i = 1, len = args.length, newObj = args[0];
                if (len > 1) {
                    for (; i < len; i++) {
                        newObj = getinterfaceArrsectionObj.call(newObj, args[i]);
                    }
                }
                return newObj;
            }
        };
    })();
    
    //压缩Object.
    ObjectUtil.shrink = function(obj) {
        var newObj = {};
        ObjectUtil.each(obj, function(key, value) {
            if (key && !ujs.Type.isUndefined(value)) {
                newObj[key] = value;
            }
        });
        return newObj;
    };
    
    /** 
     * 对象是否为空 
     * @param obj 对象 
     */  
    ObjectUtil.isNull = function(obj) {  
        return obj === null || obj === undefined || obj === '';  
    };
    
    /**
     * 反转指定obj的key与value, 适用于value为string的情况.
     * Object的key会被默认转化为string类型.
     * 
     * @param {Object} obj
     * 
     * @return {Object} newObj
     */
    ObjectUtil.reverse = function(obj){
        var newObj = {};
        for(var key in obj){
            if( obj.hasOwnProperty( key ) ) {
                newObj[ obj[key] ] = key;
            }
        }
        return newObj;
    };
    
    /**
     * 获取指定obj的指定值val相关的key.
     * 
     * @param {Object} obj
     * @param {Object} val
     */
    ObjectUtil.getKeyByValue = function(obj, val){
        if(obj){
            for(var key in obj){
                if( obj.hasOwnProperty( key ) && obj[key] === val ) {
                    return key;
                }
            }
        }
    };
    ObjectUtil.keyOf = ObjectUtil.getKeyByValue;
    
    /**
     * 判断指定对象中是否包含指定的值.
     */
    ObjectUtil.contains = function(obj, value){	 
    	return !!ObjectUtil.keyOf(obj, value);
    };
    
    /**
     * 将类数组对象转化为数组.
     * @param {Object} list
     */
    ObjectUtil.toArray = function(list) {
        return Array.prototype.slice.call(list || [], 0);
    };
    
    /**
     * 
     * @param {Object} obj
     * @param {Array} interfaceArr
     * @example node interface : ["getChildren", "getChildrenCount", "getAttr", "getName", "getProps"]
     */
    ObjectUtil.validateInterface = function(obj, interfaceArr) {
        obj = obj || {};
        interfaceArr = [].concat(interfaceArr);
        ObjectUtil.each(interfaceArr, function(i, v) {
            if (!ujs.Type.isFunction(obj[v])) {            
                return false;
            }
        });
        return true;
    };
    
    /**
     * 转化成表单对象.
     * @param {Object} obj
     */
    ObjectUtil.toFormData = function(obj){
        var formData = new FormData();
        if(ujs.Type.isObject(obj)){
            for(var key in obj){        
                formData.append(key, obj[key]);            
            }
        }
        return formData;
    };
    
    /**
     * 遍历对象中的 key-value.
     * @param {Object} obj
     * @param {Object} fun
     */
    ObjectUtil.each = function(obj, fun){
        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                var result = fun.call(obj, key, obj[key]);
                if(result === false){
                    break;
                }
            }
        }    
    };
    
    /**
     * 根据对象键值的前缀获取相关的值.
     * @param {Object} obj,
     * @param {String} prefix
     * @return {Array}
     */
    ObjectUtil.getValuesByKeyPrefix = function(obj, prefix){
    	var values = [];
    	ObjectUtil.each(obj, function(key, value){
    		if(key.startsWith(prefix)){
    			values.push(value);
    		}
    	});
    	return values;
    };
    
    /**
     * 计算对象中键值的数目。
     */
    ObjectUtil.keyCount = function(obj){
        var count = 0;
        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                count++;
            }
        }    
        return count;
    };
    ObjectUtil.getLength = ObjectUtil.keyCount;
    
    /**
     * 获取对象的所有Key数组.
     */
    ObjectUtil.getKeys = function(obj){
        var keys = [];
        for (var key in obj){
        	if(obj.hasOwnProperty(key)){ 
        		keys.push(key);
        	}
        }
        return keys;
    };
    
    /**
     * 获取对象的所有Value数组.
     */
    ObjectUtil.getValues = function(obj){
        var values = [];
        for (var key in obj){
        	if(obj.hasOwnProperty(key)){ 
        		values.push(obj[key]);
        	}
        }
        return values;
    };
    
    /**
     * 设置对象指定属性的默认值(若参数对象的属性值为null或undefined).
     * 此方法是为了增加代码的可读性.
     * @method dft
     * @static
     * @param {Object} obj 需要操作的对象.
     * @param {String} key 对象的属性名称.
     * @param {Mixed} defValue 属性默认值.
     * @return {Object} 操作的对象.
     */
    ObjectUtil.dft = function(obj, key, defValue){
        if(obj){
            if(ujs.Type.isNullOrUndefined(obj[key])){
                obj[key] = defValue;
            }
        }
        return obj;
    };
    
    /**
     * 仿jQuery继承.
     */
    ObjectUtil.extend = function () {
        var options, name, src, copy, copyIsArray, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;
    
        // Handle a deep copy situation
        if ( typeof target === "boolean" ) {
            deep = target;
            target = arguments[1] || {};
            // skip the boolean and the target
            i = 2;
        }
    
        // Handle case when target is a string or something (possible in deep copy)
        if ( typeof target !== "object" && !ujs.Type.isFunction(target) ) {
            target = {};
        }
    
        // extend Object itself if only one argument is passed
        if ( length === i ) {
            target = this;
            --i;
        }
    
        for ( ; i < length; i++ ) {
            // Only deal with non-null/undefined values
            if ( (options = arguments[ i ]) != null ) {
                // Extend the base object
                for ( name in options ) {
                    src = target[ name ];
                    copy = options[ name ];
    
                    // Prevent never-ending loop
                    if ( target === copy ) {
                        continue;
                    }
    
                    // Recurse if we're merging plain objects or arrays
                    if ( deep && copy && ( ujs.Type.isPlainObject(copy) || (copyIsArray = ujs.Type.isArray(copy)) ) ) {
                        if ( copyIsArray ) {
                            copyIsArray = false;
                            clone = src && ujs.Type.isArray(src) ? src : [];
    
                        } else {
                            clone = src && ujs.Type.isPlainObject(src) ? src : {};
                        }
    
                        // Never move original objects, clone them
                        target[ name ] = ObjectUtil.extend( deep, clone, copy );
    
                    // Don't bring in undefined values
                    } else if ( copy !== undefined ) {
                        target[ name ] = copy;
                    }
                }
            }
        }
    
        // Return the modified object
        return target;
    };
    
    /**
     * 若对象中没有指定的key，则继承使用defaultObj中的同名key。
     */
    ObjectUtil.extendIf = function(obj, defaultObj){
        return $.extend(true, {}, defaultObj, obj);
    };
    
    /**
     * 生成映射值获取函数，支持值区间key.
     * @param {Object} map
     * @return {Function}
     */
    ObjectUtil.mapping = function(map){
        return function(key){            
            key = String(key); 
            var mappingData = map[key];
            if(ujs.Type.isUndefined(mappingData)){
                ObjectUtil.each(map, function(mapKey, mapValue){
                    if(mapKey.isNumberRegion() && Number(key).isInRegion(mapKey)){
                        mappingData = map[mapKey];  
                        return false;                  
                    }
                });
            }      
            //若值为函数，则返回函数执行结果.      
            return ujs.Type.isFunction(mappingData) ? mappingData.call(map, key) : mappingData;
        };
    };
    
    /**
     * 判断指定对象的类型.
     * @notested
     * @param {Object} obj
     * @return {String|Constructor}
     */
    ObjectUtil.typeOf = function(obj){
        if(obj == undefined) return "undefined";
        if(obj == null) return 'null';
        if(obj.superFunction != null) return obj.superFunction;
    
        if(obj.nodeName){
            if(obj.nodeType == 1) return 'element';
            if(obj.nodeType == 3) return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
        }else if(typeof obj.length == 'number'){
            if(obj.callee) return 'arguments';
            if('item' in obj) return 'collection';
        }
        return typeof obj;
    };
    
    /**
     * 判断指定的对象是否是指定的构造器的实例。
     * @notested
     * @param {Object} obj
     * @param {Function} constructor
     * @return {Boolean}
     */
    ObjectUtil.instanceOf = function(obj, constructor){
        if(obj == null || obj == undefined) return false;
        //<ltIE8>
        if (!obj.hasOwnProperty) return false;
        //</ltIE8> 
        return constructor.detectInstance(obj) || (obj instanceof constructor);
    };
    
    /**
     * 深拷贝对象副本.
     */
    ObjectUtil.clone = function(obj){    	
    	return JSON.parse(JSON.stringify(obj)); 
    };
    
    /**
     * 获取对象成员的子集.
     */
    ObjectUtil.subset = function(obj, keys){
    	var results = {};
        for (var i = 0, l = keys.length; i < l; i++){
        	var k = keys[i];
          	if (k in obj) results[k] = obj[k];
        }
        return results;
    };
    
    /**
     * 将对象按指定的逻辑映射为另一个对象.
     */
    ObjectUtil.map = function(obj, fn, ctx){
    	var results = {};
        for (var key in obj){
        	if (obj.hasOwnProperty(key)){ 
        		results[key] = fn.call(ctx, obj[key], key, obj);
        	}
        }
        return results;
    };
    
    ObjectUtil.filter = function(obj, fn, ctx){
        var results = {};
        for (var key in obj){
          	var value = obj[key];
          	if (obj.hasOwnProperty(key) && fn.call(ctx, value, key, obj)){ 
          		results[key] = value;
          	}
        }
        return results;
    };
    
    ObjectUtil.every = function(obj, fn, ctx){
        for (var key in obj){
          	if (obj.hasOwnProperty(key) && !fn.call(ctx, obj[key], key, obj)){
          		return false;
          	}
        }
        return true;
    };
    
    ObjectUtil.some = function(obj, fn, ctx){
        for (var key in obj){
          	if (obj.hasOwnProperty(key) && fn.call(ctx, obj[key], key, obj)){
          		return true;
          	}
        }
        return false;
    };
    
    ObjectUtil.toQuery = function(obj){
        var queryString = [];
        ObjectUtil.each(obj, function(key, value){        
            if (!ObjectUtil.isNull(value)){
                queryString.push(key + '=' + encodeURIComponent(value));
            }
        });
        return queryString.join('&');
    };    
    
    //----------------------------------------------------------------------------------------

    //TODO 兼容性代码.    
    ujs.extend(window.Object, ObjectUtil);
    
    //----------------------------------------------------------------------------------------
    
    ujs.define('obj', 'ujs', function(){
        return ObjectUtil;
    });
    
})(window);